<title>just-ice</title>
<meta charset="UTF-8">
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>

<script type="text/babel">
  let config = {
    "iceServers": [
      {"urls": ["stun:b.7mo.org:3478"]}
    ],
    "iceTransportPolicy": "all",
    "iceCandidatePoolSize": "1"
  };

  function checkTURNServer(turnConfig, timeout) {
    return new Promise(function (resolve, reject) {

      setTimeout(function () {
        if (promiseResolved) return;
        resolve(false);
        promiseResolved = true;
      }, timeout || 5000);

      let promiseResolved = false
        , myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection   //compatibility for firefox and chrome
        , pc = new myPeerConnection({iceServers: [turnConfig]})
        , noop = function () {
      };
      pc.createDataChannel("");    //create a bogus data channel
      pc.createOffer(function (sdp) {
        if (sdp.sdp.indexOf('typ relay') > -1) { // sometimes sdp contains the ice candidates...
          promiseResolved = true;
          resolve(true);
        }
        pc.setLocalDescription(sdp, noop, noop);
      }, noop);    // create offer and set local description
      pc.onicecandidate = function (ice) {  //listen for candidate events
        if (promiseResolved || !ice || !ice.candidate || !ice.candidate.candidate || !(ice.candidate.candidate.indexOf('typ relay') > -1)) return;
        promiseResolved = true;
        resolve(true);
      };
    });

  }

  checkTURNServer({
    urls: ['turn:b.7mo.org:3478'],
    username: '',
    credential: '',
  }).then(function (bool) {
    console.log('is my TURN server active? ', bool ? 'yes' : 'no');
  }).catch(console.error.bind(console));
</script>